package edu.washington.ling.syntric.struct.tree;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Tree {
	private String layer;
	private Set<String> metaData;
	private List<Token> tokenList;
	private Map<String, Token> tokenMap;
	private int nextCoindex;
	private List<Token> dsRoots;
	private Node psRoot;
	
	// TODO: PAY ATTENTION WHEN DEBUGGING -- THIS MAY BE A SOURCE OF ERROR
	public Tree(String layer){
		this.layer = layer;
		init();
	}
	private void init() {
		metaData = new HashSet<String>();
		tokenList = new ArrayList<Token>();
		tokenMap = new HashMap<String, Token>();
		nextCoindex = 0;
		dsRoots = new ArrayList<Token>();
		psRoot = null;
	}
	public String getLayer() {
		return layer;
	}
	public void setLayer(String layer) {
		this.layer = layer;
	}
	public void addMetaData(String label) {
		metaData.add(label);
	}
	public boolean hasMetaData(String label) {
		return metaData.contains(label);
	}
	public void setMetaData(Set<String> metaData) {
		this.metaData = metaData;
	}
	public void setTokenName(Token t) {
		String name = t.getWord();
		int i = 1;
		while (tokenMap.containsKey(name)) {
			String baseName = name.replaceFirst("[0-9]+", "");
			name = baseName + i;
			i++;
		}
		t.setName(name);
	}
	public void addToken(Token t) {
		if (t.hasName() == false) {
			setTokenName(t);
		}
		tokenList.add(t);
		tokenMap.put(t.getName(), t);
	}
	public void addAllTokens(List<Token> tokens) {
		for (Token token: tokens) {
			addToken(token);
		}
	}
	public void insertTokenLeft(int position, Token t) {
		if (t.hasName() == false) {
			setTokenName(t);
		}
		tokenList.add(position, t);
		tokenMap.put(t.getName(), t);
	}
	public void insertTokenRight(int position, Token t) {
		if (t.hasName() == false) {
			setTokenName(t);
		}
		tokenList.add(position+1, t);
		tokenMap.put(t.getName(), t);
	}
	public boolean hasDSRoot() {
		return (dsRoots.size() > 0);
	}
	public void setDSRoot(Token t) {
		dsRoots = new ArrayList<Token>();
		dsRoots.add(t);
	}
	public void addDSRoot(Token t){
		dsRoots.add(t);
	}
	public void setPSRoot(Node n){
		psRoot = n;
	}
	public boolean hasTokenWithName(String name){
		return tokenMap.containsKey(name);
	}

	public int getTokenPosition(Token t) {
		return tokenList.indexOf(t);
	}
	public List<Token> getTokenList(){
		return tokenList;
	}
	public Token getTokenWithName(String name){
		return tokenMap.get(name);
	}
	public Token getTokenWithPosition(int i) {
		return tokenList.get(i);
	}
	public Token getDSRoot(){
		return dsRoots.get(0);
	}
	public List<Token> getDSRoots() {
		return dsRoots;
	}
	public boolean hasPSRoot() {
		return psRoot != null;
	}
	public Node getPSRoot(){
		return psRoot;
	}
	public int nextCoindex() {
		nextCoindex++;
		return nextCoindex;
	}
}
